﻿/// <summary>
/// <Filename>: Motion_Factory.cs
/// Author: Jiang Xiaolong
/// Created: 2015.01.27
/// Version: 1.0
/// Company: Sunnytech
/// Function: Motion运动平台接口；
///
/// Changed By:
/// Modification Time:
/// Discription:
/// <summary>
using UnityEngine;
using System.Data;
using System.Collections.Generic;
using System;
using System.Reflection;
using Motion.MotionPlatform.Tools;

namespace Motion.MotionPlatform
{
	//Motion运动控制类
	public class Motion_Factory 
	{
		//IMotion列表，为了用接口IMotion定义的方法
		public IList<IMotion> _motionList = new List<IMotion>();
		public IList<IList<IMotion>> _complexMotionList = new List<IList<IMotion>>();

		//返回当前运动类个数
		public int Count
		{
			get { return _motionList.Count + _complexMotionList.Count; }
		}

		//返回当前总时间
		public float Time
		{
			get
			{
				float _rTime = 0f;
				for (int i = 0; i < _motionList.Count; i++)
				{
					if (_motionList[i].StandardTime > _rTime)
					{
						_rTime = _motionList[i].StandardTime;					
					}
				}
				for (int i = 0; i < _complexMotionList.Count; i++)
				{
					float sumTime = 0f;
					for (int j = 0; j < _complexMotionList[i].Count; j++)
					{
						sumTime += _complexMotionList[i][j].StandardTime;
					}
					if (sumTime > _rTime)
					{
						_rTime = sumTime;
					}
				}
				return _rTime;
			}
		}

		/// <summary>
		/// TipsMotion实例；
		/// </summary>
		public TipsMotion HasTipsMotion
		{
			get { return _hasTipsMotion; }
		}
		private TipsMotion _hasTipsMotion = null;

		/// <summary>
		/// 引出线是否是顺序播放声音；
		/// </summary>
		public bool HasExtensionLineVoice
		{ 
			get { return _hasExtensionLineVoice;} 
		}
		private bool _hasExtensionLineVoice = false;

		/// <summary>
		/// 顺序出现型引出线实例；
		/// </summary>
		public DoLabelMotion ExtensionLineInstance
		{
			get { return _extensionLineInstance; }
		}
		private DoLabelMotion _extensionLineInstance = null;


		//初始化
		public void Init()
		{
			for (int i = 0; i < _motionList.Count; i++)
			{
				_motionList[i].Init();
			}
			for (int i = 0; i < _complexMotionList.Count; i++)
			{
				for (int j = 0; j < _complexMotionList[i].Count; j++)
				{
					if (_complexMotionList[i][j].State == CurrentState.Active)
					{
						_complexMotionList[i][j].Init();
						break;
					}
				}
			}
		}

		//暂停控制
		public void Pause(bool play_status)
		{
			for (int i = 0; i < _motionList.Count; i++)
			{
				_motionList[i].Pause(play_status);
			}
			for (int i = 0; i < _complexMotionList.Count; i++)
			{
				for (int j = 0; j < _complexMotionList[i].Count; j++)
				{
					if (_complexMotionList[i][j].State == CurrentState.Active)
					{
						_complexMotionList[i][j].Pause(play_status);
						break;
					}
				}
			}
			Motion_Data.PauseControl = play_status;
		}

		//改变播放速率
		public void ChangeRate(float current_rate, float current_time)
		{
			for (int i = 0; i < _motionList.Count; i++)
			{
				_motionList[i].ChangeRate(current_rate, current_time);
			}
			for (int i = 0; i < _complexMotionList.Count; i++)
			{
				for (int j = 0; j < _complexMotionList[i].Count; j++)
				{
					if (_complexMotionList[i][j].State != CurrentState.Old)
					{
						_complexMotionList[i][j].ChangeRate(current_rate, current_time);
					}
				}
			}
			Motion_Data.SpeedRate = current_rate;
		}

		//每个运动的时间控制
		public bool TimesUp(float current_time)
		{
			//简单动画部分
			bool simpleResult = true;
			for (int i = 0; i < _motionList.Count; i++)
			{
				bool singleResult = _motionList[i].TimesUp(current_time);
				if (i == 0)
					simpleResult = singleResult;
				else
					simpleResult = simpleResult && singleResult;
				if (singleResult)
				{
					_motionList[i].PostProcess();
					_motionList.RemoveAt(i);
					i--;
				}
			}

			//组合动画部分
			bool complexResult = true;
			for (int i = 0; i < _complexMotionList.Count; i++)
			{
				bool singleResult = true;
				for (int j = 0; j < _complexMotionList[i].Count; j++)
				{
					if (_complexMotionList[i][j].State == CurrentState.Active)
					{
						singleResult = _complexMotionList[i][j].TimesUp(current_time);
						if (singleResult)
						{
							_complexMotionList[i][j].State = CurrentState.Old;
							_complexMotionList[i][j].PostProcess();
							if (j != _complexMotionList[i].Count - 1)
							{
								_complexMotionList[i][j + 1].State = CurrentState.Active;
								_complexMotionList[i][j + 1].StartTime = current_time;
								_complexMotionList[i][j + 1].EndTime += current_time;
								_complexMotionList[i][j + 1].Init();
								singleResult = false;
							}
							_complexMotionList[i].RemoveAt(j);
							break;
						}
					}
				}
				if (i == 0)
					complexResult = singleResult;
				else
					complexResult = complexResult && singleResult;
			}


			return simpleResult && complexResult;
		}

		//运动
		public void Move(float current_time, float speed_rate, float delta_time)
		{
			for (int i = 0; i < _motionList.Count; i++)
			{
				_motionList[i].Move(current_time, speed_rate, delta_time);
			}
			for (int i = 0; i < _complexMotionList.Count; i++)
			{
				for (int j = 0; j < _complexMotionList[i].Count; j++)
				{
					if (_complexMotionList[i][j].State == CurrentState.Active)
					{
						_complexMotionList[i][j].Move(current_time, speed_rate, delta_time);
						break;
					}
				}
			}
		}

		/// <summary>
		/// 通用运动工厂类，承担类似抽象工程的职责；
		/// </summary>
		/// <param name="motion_symbol">运动标识符，相当于Sheet名，表格扩展了一个新功能时会增加；</param>
		/// <param name="data_row">当前数据行；</param>
		/// <param name="id">当前数据行id，用于错误定位；</param>
		/// <param name="group_table">运动组Table；</param>
		/// <returns>是否解析成功；</returns>
		public bool FactoryCreate(string motion_symbol, int state, DataRow data_row, string id, DataTable group_table)
		{
			if (Application.isEditor && !Motion_EditorEncryption.IsAllowEditor)
			{
				Debug.LogError("运动平台被加密，请检查该解密文件是否正确，路径：" + Application.dataPath + "/Editor_Key.txt");
				return false;
			}

			if (Motion_Data.FucntionParseDic.ContainsKey(motion_symbol))
			{
				//加载Type
				Type _t = Motion_TypeGet.MotionTypeGet("Motion.MotionPlatform." + Motion_Data.FucntionParseDic[motion_symbol]);
				//判断Type是否为空
				if (_t == null)
				{
					Debug.LogError("Type: " + "Motion.MotionPlatform." + Motion_Data.FucntionParseDic[motion_symbol] + "，该类型在所有程序集中都不存在！");
					return false;
				}
				//实例化相应的解析类
				IMotionInfoManager infoInstance = (IMotionInfoManager)Activator.CreateInstance(_t);

				//PANEL单独处理，因为要提取其中与输入框关联的变量，以便修改输入框对应的变量
				//PROGRAM中特效需要单独，因为要提取与特效相关的变量，以便通过修改该变量来控制特效

				if (motion_symbol != "PANEL" && !(motion_symbol == "PROGRAM" && data_row[2].ToString() == "Particle"))
				{
					Motion_Compute.ExcelDataAnalysis(ref data_row, motion_symbol, group_table);
				}
				bool result = infoInstance.InfoGet(motion_symbol, state, data_row, id, group_table, _motionList, _complexMotionList);
				if (result)
				{
					if (_motionList.Count > 0 && _motionList[_motionList.Count - 1].GetType() == typeof(TipsMotion))  //Tips特殊处理
					{
						//Debug.Log("TODO: Yes! TipsMotion Got!");
						_hasTipsMotion = (TipsMotion)_motionList[_motionList.Count - 1];
					}
					else if (_motionList.Count > 0 && _motionList[_motionList.Count - 1].GetType() == typeof(DoLabelMotion))  //顺序型引出线特殊处理
					{
						//Debug.Log("TODO: Yes! DoLabelMotion Got!");
						if (!((DoLabelMotion)_motionList[_motionList.Count - 1]).showType)
						{
							_hasExtensionLineVoice = true;
							_extensionLineInstance = (DoLabelMotion)_motionList[_motionList.Count - 1];
						}
					}
				}
				return result;
			}
			else
			{
				Debug.LogError("运动标志符：" + motion_symbol + "，不含有该运动标志符对应的解析类，请询问相关程序猿！");
				return false;
			}
		}

		//List Clear
		public void Clear()
		{
			_motionList.Clear();
			_complexMotionList.Clear();
			_hasTipsMotion = null;
			_hasExtensionLineVoice = false;
			_extensionLineInstance = null;
		}

		//停止时的后处理
		public void PostProcess()
		{
			for (int i = 0; i < _motionList.Count; i++)
			{
				_motionList[i].PostProcess();
			}
			for (int i = 0; i < _complexMotionList.Count; i++)
			{
				for (int j = 0; j < _complexMotionList[i].Count; j++)
				{
					_complexMotionList[i][j].PostProcess();
				}
			}
		}
	}
}
